package com.liy.framework.web.spring.aop;

import com.liy.framework.common.extvo.LogAttributeInfo;
import com.liy.framework.web.spring.utils.WebTools;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


/**
  系统AOP拦截产出Log   Aspect切面类
*/
public class SystemOperationLogAspect {

    protected static Logger log = LoggerFactory.getLogger(SystemOperationLogAspect.class);

    private long startTime = 0L;

    public SystemOperationLogAspect() {
    }


    /**
     *   定义切点   注解为 RequestMapping 的地方  凡是有  RequestMapping的地方 均是切点所在
     */
    @Pointcut("@annotation(org.springframework.web.bind.annotation.RequestMapping)")
    private void anyMethod() {
    }



    /**
     *   异常 通知
     */
    @AfterThrowing(
            pointcut = "anyMethod()",   //指定切点: 上边定义的切点
            throwing = "e"
    )
    public void doAfterThrow(JoinPoint joinPoint, Throwable e) {


        // 通过 RequestContextHolder 拿到 RequestAttributes
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();

        // 强转为 ServletRequestAttributes
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) requestAttributes;

        HttpServletRequest httpServletRequest = servletRequestAttributes.getRequest();

        // 拿到请求的地址
        String requestURL = httpServletRequest.getRequestURL().toString();


        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

        long time = System.currentTimeMillis() - this.startTime;

        String tip = time > 1000L ? "超过设定值1000ms" : "";

        log.info(String.format("服务：%s, 处理耗时[%dms],%s, 处理异常：%s", request.getRequestURL(), time, tip, e.getMessage()), e, new LogAttributeInfo(request.getRequestURL().toString(), time));
    }


    /**
     *   环绕 通知
     */
    @Around("anyMethod()")  //指定切点: 上边定义的切点
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {

        this.startTime = System.currentTimeMillis();

        // 请求方法
        HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();


        // 执行 本身的方法
        Object object = pjp.proceed();

        long time = System.currentTimeMillis() - this.startTime;

        String tip = time > 1000L ? "超过设定值1000ms" : "";

        log.info(String.format("服务：%s,处理耗时[%dms],%s,响应数据：%s", request.getRequestURL(), time, tip, object != null ? object.toString() : "null"), new LogAttributeInfo(request.getRequestURL().toString(), time));

        Map<?, ?> params2 = WebTools.getRequestParams(request);

        log.info("请求参数：" + params2.toString());

        if (log.isDebugEnabled()) {
            Map<?, ?> params = WebTools.getRequestParams(request);
            log.info("请求参数：" + params.toString());
        }

        return object;
    }
}
